home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)textarray.c V1.30 3/13/95";
- #endif
- /* file name - textarray.c
- |===================================================================
- |
- | module description/function:
- | Example program for VUtextarray routines.
- |
- | This program creates two text arrays,
- | one for input and display, the other for output only.
- | When the cursor is in the input text array,
- | characters are echoed as they are typed.
- | When a carriage-return or linefeed is hit, the entire line
- | is echoed to the output only text array.
- |
- |
- | The following characters are handled in a special way:
- | ^R refresh both text arrays
- |
- |
- | The following chars have special meaning in the input area:
- |
- | ^U deletes the entire line
- | ^W deletes the current word
- | ^L (FORM FEED) clear both text arrays
- | ^H (BKSP) or 0x7f (DEL) back up one character
- | ^J (LF) or ^M (CR) move cursor to next line and echo input
- | text array line to output text array
- | ^I (TAB) move cursor to next tab stop.
- | (One tab stop every eight columns.)
- |
- |
- | The following keys have special meaning in the input area:
- |
- | LEFT mouse button (1) Temporarily highlight one character
- | MIDDLE mouse button (2) Temporarily highlight string from
- | highlighted character to cursor
- |
- |
- | Quitting can be accomplished in any of the following ways:
- | -- Pressing 'q' or 'Q' outside of the input text array.
- | -- Pressing the RIGHT mouse button (3) anywhere in the window.
- | -- Pressing the <ESC> key anywhere in the window.
- |
- |===================================================================
- |
- | Possible enhancements:
- | -- Teach the program to know about obscuring viewports. Eg. let
- | one text array (partially or entirely) obscure the other.
- | And/or have obscuring objects maintain their integrity.
- |
- |===================================================================
- */
-
- #include <windows.h>
- #include "std.h"
- #include "dvstd.h"
- #include "dvtools.h"
- #include "Tfundecl.h"
- #include "VOfundecl.h"
- #include "VUfundecl.h"
- #include "GRfundecl.h"
- #include "VUtextarray.h"
-
- #define DEFAULT_DEVICE_NAME NULL /* Use config var DVDEVICE */
- #define DEFAULT_LAYOUT_FILE "ta.lay"
- #define DEFAULT_SEARCH_PATH NULL /* Use config var DVPATH */
-
- /* Names of named objects in template */
- #define INPUT "input" /* place for input textarray */
- #define OUTPUT "output" /* place for output textarray */
- #define VISIBLE_AREA "visible.area" /* defines what portion of
- view is to be visible */
-
- #ifndef __FILE__
- #define __FILE__ "textarray.c"
- #endif
-
- /* Characters with which to do blank fill */
- #define BLANK_CHAR_IN '_' /* on input */
- #define BLANK_CHAR_OUT ' ' /* on output */
-
- LOCAL RECTANGLE /* coordinates of full screen */
- vfull_screen =
- {
- {0, 0},
- {MAXCOORD, MAXCOORD}}, /* virtual coords */
- sfull_screen =
- {
- {0, 0},
- {0, 0}}; /* screen coordinates */
-
- /* typedefs */
- typedef struct terminal
- {
- TEXTARRAY ta; /* the text array */
- TA_POSITION curpos; /* position of the cursor */
- DV_BOOL curdisp; /* cursor displayed? */
- } TERMINAL;
-
- /* macros */
- #define GET_CURSOR_POSITION( t, r, c ) ( (r) = (t)->curpos.row,\
- (c) = (t)->curpos.col,\
- &(t)->curpos )
- /*
- argv[1] - display device (default is DVDEVICE)
- argv[2] - layout for where to put objects (default is ta.lay)
- argv[3] - search path (default is DVPATH)
- */
-
- /* Functions defined in textarray.c */
- LOCAL DV_BOOL HandlePick V_P_((int key, int row_picked, int col_picked,
- TERMINAL *in, TERMINAL *out));
- LOCAL void Scroll V_P_((TERMINAL *t, int blank_char));
- LOCAL DV_BOOL PresentCursor V_P_((TERMINAL *t, BOOLPARAM disp));
- LOCAL DV_BOOL AdjustHighlight V_P_((TEXTARRAY ta, TA_POSITION *p1,
- TA_POSITION *p2, TA_POSITION *p));
- LOCAL void MoveCursor V_P_((TERMINAL *t, int row, int col));
- LOCAL void TaPosInc V_P_((TEXTARRAY ta, TA_POSITION *p));
- LOCAL void TaPosDec V_P_((TEXTARRAY ta, TA_POSITION *p));
- LOCAL void TaPosMidpt V_P_((TEXTARRAY ta, TA_POSITION *p1, TA_POSITION *p2,
- TA_POSITION *mid));
- LOCAL DV_BOOL Reverse V_P_((TEXTARRAY ta, TA_POSITION *p1,
- TA_POSITION *p2));
- LOCAL int TaPosCmp V_P_((TA_POSITION *p1, TA_POSITION *p2));
- LOCAL void TaPosSort V_P_((TA_POSITION **p1, TA_POSITION **p2));
- LOCAL char *Repl V_P_((char *buf, int from, int to));
- LOCAL void Boxta V_P_((TEXTARRAY ta, int color));
- LOCAL void PickRegion V_P_((char *msg, RECTANGLE *region));
- LOCAL void Cross V_P_((DV_POINT *pt, int color));
- LOCAL void GetScrBox V_P_((OBJECT obj, RECTANGLE *svp));
- LOCAL void DrawBox V_P_((RECTANGLE *r, int color));
- LOCAL void RectExpand V_P_((RECTANGLE *r, DV_COORD p));
- LOCAL void cpybuf V_P_((char *to, char *from, int numchars));
- LOCAL void Usage V_P_((char *ProgName));
- /***************** End Function Declarations *************/
-
- int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
-
- {
- INT argc = 0;
- CHAR **argv;
-
- #define ESC 0x1B /* the Escape key */
- #define REFRESH 0x12 /* ^R */
- char *layout_file = DEFAULT_LAYOUT_FILE;
- char *search_path = DEFAULT_SEARCH_PATH;
- OBJECT screen;
- OBJECT layout = (OBJECT) 0;
- OBJECT
- input = (OBJECT) 0,
- output = (OBJECT) 0;
- LOCAL TA_POSITION minsiz =
- {2, 2}; /* minimum size for each ta */
- LOCAL DV_POINT /* Points to fix input and output text arrays */
- InPt =
- {0, 0}, OutPt =
- {0, 0};
- LOCAL DV_POINT /* Sizes of input and output text arrays */
- InSz =
- {0, 0}, OutSz =
- {0, 0};
- int poll_type = WAIT_PICK;
- LOCAL TERMINAL
- in, /* input area */
- out; /* output area */
- int /* local foreground & background color indices */
- in_fore, in_back,
- out_fore, out_back;
- TA_RECT fullrect;
- RECTANGLE in_svp;
- RECTANGLE out_svp;
- DRAWPORT dp = (DRAWPORT) 0;
- VIEW view;
- int rc = EXIT_OK;
- char *prog_name = __FILE__;
-
- /* Initialize search path */
- if (argc > 3 && argv[3])
- search_path = argv[3];
- make_argv(&argc,&argv,GetCommandLine());
- TInit (search_path, (char *) NULL);
-
- /* Open display device */
- if (argc > 1)
- screen = TscOpenSet (argv[1], (char *) NULL,
- V_X_EXPOSURE_BLOCK, YES, V_END_OF_LIST);
- else
- screen = TscOpenSet ((char *) NULL, (char *) NULL,
- V_X_EXPOSURE_BLOCK, YES, V_END_OF_LIST);
- if (!screen)
- {
- printf ("Must specify device on command line or");
- printf (" in DataViews configuration file.\n");
- TTerminate ();
- exit (EXIT_ERR);
- }
-
- /* Get screen coordinates of full screen */
- GRvcs_to_scs (&vfull_screen.ll, &sfull_screen.ll);
- GRvcs_to_scs (&vfull_screen.ur, &sfull_screen.ur);
-
- /* Get info from layout, if available */
- if (argc > 2 && argv[2])
- layout_file = argv[2];
- if (layout_file && 0 != strcmp (layout_file, "0") &&
- (layout = TviGetDrawing (view = TviLoad (layout_file))))
- {
- /* Get location of input text array */
- input = TdrGetNamedObject (layout, INPUT);
- if (input)
- /* set parameters to VUtaCreate for input textarray */
- {
- GetScrBox (input, &in_svp);
- cpybuf ((char *) & InPt, (char *) & in_svp.ll, sizeof (in_svp.ll));
- InSz.x = in_svp.ur.x - in_svp.ll.x + 1;
- InSz.y = in_svp.ur.y - in_svp.ll.y + 1;
- VOdrObDelete (layout, VOobReference (input));
- }
-
- /* Get location of output text array */
- output = TdrGetNamedObject (layout, OUTPUT);
- if (output)
- /* set parameters to VUtaCreate for output textarray */
- {
- GetScrBox (output, &out_svp);
- cpybuf ((char *) & OutPt,
- (char *) & out_svp.ll, sizeof (out_svp.ll));
- OutSz.x = out_svp.ur.x - out_svp.ll.x + 1;
- OutSz.y = out_svp.ur.y - out_svp.ll.y + 1;
- VOdrObDelete (layout, VOobReference (output));
- }
- }
-
- /* Initialize info that was unavailable from layout */
- if (!input || !output)
- {
- TscErase (screen);
- if (!input)
- {
- PickRegion ("Pick two points for input text array.",
- &in_svp);
- cpybuf ((char *) & InPt, (char *) & in_svp.ll, sizeof (InPt));
- InSz.x = in_svp.ur.x - in_svp.ll.x + 1;
- InSz.y = in_svp.ur.y - in_svp.ll.y + 1;
- }
- if (!output)
- {
- PickRegion ("Pick two points for output text array.",
- &out_svp);
- cpybuf ((char *) & OutPt, (char *) & out_svp.ll, sizeof (OutPt));
- OutSz.x = out_svp.ur.x - out_svp.ll.x + 1;
- OutSz.y = out_svp.ur.y - out_svp.ll.y + 1;
- }
- }
-
- /* Create the textarrays */
- in.ta = VUtaCreate ((ULONG) (V_OP_LL | V_RSLVE_GREATER | V_SLOP_SHRINK),
- &InPt, &InSz, &minsiz,
- DEF_TEXT_SIZE, (int *) NULL);
- out.ta = VUtaCreate ((ULONG) (V_OP_LL | V_RSLVE_GREATER | V_SLOP_SHRINK),
- &OutPt, &OutSz, &minsiz,
- DEF_TEXT_SIZE, (int *) NULL);
- if (!in.ta || !out.ta)
- {
- fprintf (
- stderr, "%s: Could not create %s\n", prog_name,
- in.ta ? "output textarray" :
- (out.ta ? "input textarray" : "input or output textarray"));
- rc = EXIT_ERR;
- goto err_exit;
- }
- else
- {
- in_back = VUtaGetColor (in.ta, 0);
- in_fore = VUtaGetColor (in.ta, 1);
- out_back = VUtaGetColor (out.ta, 0);
- out_fore = VUtaGetColor (out.ta, 1);
- }
- /* Get real bounding box of text arrays */
- VUtaBox (in.ta, &in_svp);
- VUtaBox (out.ta, &out_svp);
-
- /* Erase the screen before doing any graphics */
- TscErase (screen);
-
- /* Draw decoration, if any */
- if (view && layout)
- {
- LOCAL RECTANGLE wvp_drawing =
- {
- {-16383, -16383},
- {16383, 16383}};
- RECTANGLE svp_delta;
- OBJECT visible_area;
-
- /* Get bounding box of area to display */
- visible_area = TdrGetNamedObject (layout, VISIBLE_AREA);
- if (visible_area)
- VOobBox (visible_area, &wvp_drawing, &svp_delta);
- else
- VOobBox (layout, &wvp_drawing, &svp_delta);
-
- /* Try to make sense of the svp_delta */
- GRscs_to_vcs (&svp_delta.ll, &svp_delta.ll);
- GRscs_to_vcs (&svp_delta.ur, &svp_delta.ur);
- wvp_drawing.ll.x += svp_delta.ll.x;
- wvp_drawing.ll.y += svp_delta.ll.y;
- wvp_drawing.ur.x += svp_delta.ur.x;
- wvp_drawing.ur.y += svp_delta.ur.y;
-
- /* Create drawport */
- dp = TdpCreateStretch (screen, view,
- (RECTANGLE *) NULL, &wvp_drawing);
- TdpDraw (dp);
- }
-
- /* Draw rectangles around the text arrays */
- Boxta (in.ta, in_fore);
- Boxta (out.ta, out_fore);
-
- /* fill text arrays with underscores and set cursor positions */
- V_TRSET (&fullrect, 0, 0,
- VUtaGetHeight (in.ta) - 1,
- VUtaGetWidth (in.ta) - 1);
- VUtaFillRect (in.ta, &fullrect, BLANK_CHAR_IN, V_TA_NORMAL);
- V_TPSET (&in.curpos, 0, 0);
- in.curdisp = NO;
- V_TRSET (&fullrect, 0, 0,
- VUtaGetHeight (out.ta) - 1,
- VUtaGetWidth (out.ta) - 1);
- VUtaFillRect (out.ta, &fullrect, BLANK_CHAR_OUT, V_TA_NORMAL);
- V_TPSET (&out.curpos, 0, 0);
- out.curdisp = NO;
-
- /* Show cursor on input, but not on output */
- PresentCursor (&in, (DV_BOOL) YES);
- PresentCursor (&out, (DV_BOOL) NO);
- VUtaDraw (in.ta, (RECTANGLE **) NULL);
- VUtaDraw (out.ta, (RECTANGLE **) NULL);
- GRflush ();
-
- /* Get input from in.ta and output it to out.ta */
- FOREVER
- {
- DV_BOOL curdisp_in; /* cursor displayed in input text array? */
- DV_BOOL curdisp_out; /* cursor displayed in output text array? */
- OBJECT loc;
- int key;
- DV_POINT p;
- TA_POSITION tp; /* general purpose character position */
- DV_BOOL err = DV_SUCCESS; /* possible error from called routines */
-
-
- loc = TloPoll (poll_type);
- key = VOloKey (loc);
- cpybuf ((char *) & p, (char *) VOloScpGet (loc), sizeof (p));
- if ('\003' == key || ESC == key) /* quit */
- break;
- else if (REFRESH == key)
- {
- /* Get new upper right portion of screen */
- GRreset ();
- GRvcs_to_scs (&vfull_screen.ur, &p);
- if (p.x != sfull_screen.ur.x || p.y != sfull_screen.ur.y)
- {
- TEXTARRAY /* the (now) old text arrays */
- old_in = in.ta,
- old_out = out.ta;
- /* height and width of (now) old and new text arrays */
- int old_height, new_height;
- int old_width, new_width;
- TA_RECT crect; /* char rect used for rectangular fills */
-
- /* Set new screen dimensions */
- sfull_screen.ur.x = p.x;
- sfull_screen.ur.y = p.y;
-
- /* Recalculate drawports */
- err &= TscReset (screen);
- /* On some window systems we may not need to redraw, as resizing
- | also generates an expose event. Others may never generate
- | expose events. On still others, enlarging
- | a window generates an expose, but shrinking doesn't.
- | To be as general as possible, here we will always
- | redraw the screen even though some users will see
- | two redraws.
- */
- TscRedraw (screen, (RECTANGLE *) NULL);
-
- /* Recalculate boundaries of text arrays */
- if (input)
- {
- GetScrBox (input, &in_svp);
- cpybuf ((char *) & InPt,
- (char *) & in_svp.ll, sizeof (in_svp.ll));
- InSz.x = in_svp.ur.x - in_svp.ll.x + 1;
- InSz.y = in_svp.ur.y - in_svp.ll.y + 1;
- }
-
- if (output)
- {
- GetScrBox (output, &out_svp);
- cpybuf ((char *) & OutPt,
- (char *) & out_svp.ll, sizeof (out_svp.ll));
- OutSz.x = out_svp.ur.x - out_svp.ll.x + 1;
- OutSz.y = out_svp.ur.y - out_svp.ll.y + 1;
- }
-
- /* Create the new textarrays (resize with new window size) */
- in.ta =
- VUtaCreate ((ULONG) (V_OP_LL | V_RSLVE_GREATER | V_SLOP_SHRINK),
- &InPt, &InSz, &minsiz,
- DEF_TEXT_SIZE, (int *) NULL);
- out.ta =
- VUtaCreate ((ULONG) (V_OP_LL | V_RSLVE_GREATER | V_SLOP_SHRINK),
- &OutPt, &OutSz, &minsiz,
- DEF_TEXT_SIZE, (int *) NULL);
-
- /* Copy the contents of the old text arrays into the new ones */
- err &= VUtaCopyRect (in.ta, (TA_RECT *) NULL,
- old_in, (TA_RECT *) NULL);
- err &= VUtaCopyRect (out.ta, (TA_RECT *) NULL,
- old_out, (TA_RECT *) NULL);
-
- /* If either text array got bigger,
- | fill out the enlarged parts with
- | the appropriate blank characters. */
- old_height = VUtaGetHeight (old_in);
- new_height = VUtaGetHeight (in.ta);
- old_width = VUtaGetWidth (old_in);
- new_width = VUtaGetWidth (in.ta);
- if (new_width > old_width)
- err &= VUtaFillRect (in.ta,
- V_TRSET (&crect, 0, old_width,
- old_height - 1, new_width - 1),
- BLANK_CHAR_IN, V_TA_NORMAL);
- if (new_height > old_height)
- err &= VUtaFillRect (in.ta,
- V_TRSET (&crect, old_height, 0,
- new_height - 1, new_width - 1),
- BLANK_CHAR_IN, V_TA_NORMAL);
- old_height = VUtaGetHeight (old_out);
- new_height = VUtaGetHeight (out.ta);
- old_width = VUtaGetWidth (old_out);
- new_width = VUtaGetWidth (out.ta);
- if (new_width > old_width)
- err &= VUtaFillRect (out.ta,
- V_TRSET (&crect, 0, old_width,
- old_height - 1, new_width - 1),
- BLANK_CHAR_OUT, V_TA_NORMAL);
- if (new_height > old_height)
- err &= VUtaFillRect (out.ta,
- V_TRSET (&crect, old_height, 0,
- new_height - 1, new_width - 1),
- BLANK_CHAR_OUT, V_TA_NORMAL);
-
- /* Adjust cursor positions, if necessary */
- if (in.curpos.row >= new_height || in.curpos.col >= new_width)
- {
- in.curpos.row = S_MIN (in.curpos.row, new_height - 1);
- in.curpos.col = S_MIN (in.curpos.col, new_width - 1);
- err &= VUtaSwapColor (in.ta, &in.curpos, 1);
- }
- if (out.curpos.row >= new_height || out.curpos.col >= new_width)
- {
- out.curpos.row = S_MIN (out.curpos.row, new_height - 1);
- out.curpos.col = S_MIN (out.curpos.col, new_width - 1);
- err &= VUtaSwapColor (out.ta, &out.curpos, 1);
- }
-
- /* Destroy old text arrays */
- err &= VUtaDestroy (old_in);
- err &= VUtaDestroy (old_out);
-
- /* Get real bounding box of text arrays */
- VUtaBox (in.ta, &in_svp);
- VUtaBox (out.ta, &out_svp);
- }
-
- /* Draw decoration, if any */
- if (dp)
- err &= TdpRedraw (dp, (RECTANGLE *) NULL, YES);
- else
- err &= TscErase (screen);
-
- /* Draw rectangles around the text arrays */
- Boxta (in.ta, in_fore);
- Boxta (out.ta, out_fore);
-
- /* refresh input objects */
- err &= VUtaRedraw (in.ta, (RECTANGLE **) NULL);
- err &= VUtaRedraw (out.ta, (RECTANGLE **) NULL);
-
- err &= GRflush ();
- if (DV_FAILURE == err)
- {
- rc = EXIT_ERR;
- break;
- }
- }
-
- else if (VUtaScreenToChar (in.ta, &p, &tp))
- {
- /* Turn cursors off */
- curdisp_in = PresentCursor (&in, (DV_BOOL) NO);
- curdisp_out = PresentCursor (&out, (DV_BOOL) NO);
-
- /* Handle the user pick */
- if (!HandlePick (key, tp.row, tp.col, &in, &out))
- {
- rc = EXIT_ERR;
- break;
- }
-
- /* Turn the cursors back on */
- PresentCursor (&in, curdisp_in);
- PresentCursor (&out, curdisp_out);
-
- /* Draw text arrays to the screen */
- err &= VUtaDraw (in.ta, (RECTANGLE **) NULL);
- err &= VUtaDraw (out.ta, (RECTANGLE **) NULL);
- err &= GRflush ();
- }
- else if ('q' == key || 'Q' == key) /* quit */
- break;
- }
-
- /* Clean up and exit */
- if (input)
- VOobDereference (input);
- if (output)
- VOobDereference (output);
- if (dp)
- TdpDestroy (dp);
- GRcolor (in_back);
- GRf_rectangle (&in_svp.ll, &in_svp.ur);
- GRcolor (out_back);
- GRf_rectangle (&out_svp.ll, &out_svp.ur);
-
- err_exit:
- if (in.ta)
- VUtaDestroy (in.ta);
- if (out.ta)
- VUtaDestroy (out.ta);
- if (view)
- TviDestroy (view);
- TscErase (screen);
- TscClose (screen);
- TTerminate ();
- return rc;
- }
-
- /* HandlePick()
- |
- | Handle the character that was typed
- | in the region of the input text array.
- */
- LOCAL DV_BOOL
- HandlePick (key, row_picked, col_picked, in, out)
- int key;
- int row_picked;
- int col_picked;
- TERMINAL *in;
- TERMINAL *out;
- {
- #define DELETE_LINE 0x15 /* ^U */
- #define DELETE_WORD 0x17 /* ^W */
- #define DELETE_CHAR 0x7F /* DEL key */
- #define CLEAR_TAS '\f' /* ^L -- clear both text arrays */
- #define TAB_STOP 8
- LOCAL DV_BOOL wraparound = YES;
- LOCAL char us = BLANK_CHAR_IN;
- LOCAL char *buf = NULL;
- DV_BOOL rc = DV_SUCCESS; /* return code */
- int
- row,
- col,
- in_height,
- in_width,
- out_row,
- out_col,
- out_height,
- out_width,
- width;
- TA_RECT trect;
- static TA_POSITION
- p1 =
- {-1, -1}, p2 =
- {-1, -1};
- TA_POSITION tp; /* general purpose character position */
- char *bptr; /* ptr for backing up to beginning of word */
- char *dptr; /* ptr for deleting chars within a word */
-
-
- /* Get current position of cursor */
- GET_CURSOR_POSITION (in, row, col);
-
- /* Get height and width of text arrays */
- in_height = VUtaGetHeight (in->ta);
- in_width = VUtaGetWidth (in->ta);
- out_height = VUtaGetHeight (out->ta);
- out_width = VUtaGetWidth (out->ta);
-
- /* Initialize buffer */
- if (!buf)
- buf = S_ALLOC ((unsigned)in_width + 1);
-
- /* If not highlighting, undo effects of existing highlighting */
- if ('\002' != key)
- {
- if (p1.row >= 0 && p1.col >= 0)
- if (p2.row >= 0 && p2.col >= 0)
- rc &= Reverse (in->ta, &p1, &p2);
- else
- rc &= Reverse (in->ta, &p1, &p1);
- p1.row = p1.col = p2.row = p2.col = -1;
- }
-
- /* Deal with the key in its own special way */
- switch (key)
- {
- case '\000': /* Ignore weird keys like <SHIFT> and <CTL> */
- break;
-
- case '\001': /* left mouse button: highlight one character */
- p1.row = p2.row = row_picked;
- p1.col = p2.col = col_picked;
- rc &= Reverse (in->ta, &p1, &p1);
- break;
-
- case '\002': /* middle mouse button: highlight region */
- if (p1.row >= 0 && p1.col >= 0)
- {
- TA_POSITION ptmp;
-
- if (p2.row < 0 || p2.col < 0)
- {
- p2.row = p1.row;
- p2.col = p1.col;
- }
- ptmp.row = row_picked;
- ptmp.col = col_picked;
- rc &= AdjustHighlight (in->ta, &p1, &p2, &ptmp);
- }
- break;
-
- case DELETE_LINE: /* delete entire line */
- MoveCursor (in, row, 0);
- rc &= VUtaPutChar (in->ta, BLANK_CHAR_IN, V_TA_NORMAL,
- V_TPSET (&tp, row, 0), in_width);
- break;
-
- case DELETE_WORD: /* delete previous word */
- /* Get string up to cursor position */
- if (strlen (VUtaGetString (in->ta, buf, (TA_PACKED_COLOR *) NULL,
- V_TPSET (&tp, row, 0), col)) <= 0)
- break;
-
- /* eliminate trailing blanks */
- for (bptr = buf + strlen (buf); bptr > buf; bptr--)
- if (*(bptr - 1) != BLANK_CHAR_IN &&
- *(bptr - 1) != BLANK_CHAR_OUT)
- break;
-
- /* eliminate word itself */
- while (bptr > buf)
- if (BLANK_CHAR_IN == *(bptr - 1) ||
- BLANK_CHAR_OUT == *(bptr - 1))
- break;
- else
- bptr--;
-
- /* delete the word in the buffer */
- for (dptr = bptr; *dptr; dptr++)
- *dptr = BLANK_CHAR_IN;
-
- /* write altered part of the buffer back to the text array */
- rc &= VUtaPutString (in->ta, bptr, V_TA_NORMAL,
- V_TPSET (&tp, row, bptr - buf), -1);
-
- /* Move cursor back */
- in->curpos.col -= strlen (bptr);
- break;
-
- case '\t': /* tab: write spaces to next tab stop */
- if (col < in_width - 1)
- do
- rc &= VUtaPutChar (in->ta, BLANK_CHAR_IN, V_TA_NORMAL,
- V_TPSET (&tp, row, col++), 1);
- while (col < in_width - 1 && col % TAB_STOP != 0);
- if (col >= in_width)
- col--;
- MoveCursor (in, row, col);
- break;
-
- case '\b': /* backspace: back up one character */
- case DELETE_CHAR: /* treat the delete key same as the backspace */
- if (col > 0)
- {
- rc &= VUtaPutChar (in->ta, us, V_TA_NORMAL,
- V_TPSET (&tp, row, col - 1), 1);
- MoveCursor (in, row, col - 1);
- }
- break;
-
- case CLEAR_TAS: /* form feed: clear both textarrays */
- V_TRSET (&trect, 0, 0, in_height - 1, in_width - 1);
- rc &= VUtaFillRect (in->ta, &trect,
- BLANK_CHAR_IN, V_TA_NORMAL);
- MoveCursor (in, 0, 0);
- V_TRSET (&trect, 0, 0, out_height - 1, out_width - 1);
- rc &= VUtaFillRect (out->ta, &trect,
- BLANK_CHAR_OUT, V_TA_NORMAL);
- MoveCursor (out, 0, 0);
- break;
-
- default: /* simply display char */
- rc &= VUtaPutChar (in->ta, key, V_TA_NORMAL,
- V_TPSET (&tp, row, col), 1);
- if (++col < in_width || !wraparound)
- {
- MoveCursor (in, row, col);
- break;
- }
- /* else scroll */
-
- case '\r': /* Treat CR the same as newline */
- case '\n': /* new line: flush line to output ta */
- /* flush to out->ta */
- width = S_MIN (in_width, out_width);
- if (strlen (VUtaGetString (in->ta, buf, (TA_PACKED_COLOR *) NULL,
- V_TPSET (&tp, row, 0), width)) > 0)
- {
- LOCAL DV_BOOL first_time_last_line = YES;
-
- GET_CURSOR_POSITION (out, out_row, out_col);
- if (out_row >= out_height - 1)
- if (first_time_last_line)
- first_time_last_line = NO;
- else
- Scroll (out, BLANK_CHAR_OUT);
- rc &= VUtaPutString (out->ta,
- Repl (buf, BLANK_CHAR_IN,
- BLANK_CHAR_OUT),
- V_TA_NORMAL,
- V_TPSET (&tp, out_row, out_col),
- out_width);
- if (out_row < out_height - 1)
- MoveCursor (out, ++out_row, 0);
- }
- if (row >= in_height - 1)
- Scroll (in, BLANK_CHAR_IN);
- else
- MoveCursor (in, ++row, 0);
- break;
- }
-
- return rc;
- }
-
- /* Scroll()
- |
- | Scroll the given textarray up by one row.
- | Assumes the cursor is not currently displayed.
- */
- LOCAL void
- Scroll (t, blank_char)
- TERMINAL *t;
- int blank_char;
- {
- int height, width;
- TA_RECT trect;
-
- /* Get height and width of text arrays */
- height = VUtaGetHeight (t->ta);
- width = VUtaGetWidth (t->ta);
-
- V_TRSET (&trect, 1, 0, height - 1, width - 1);
- VUtaMoveRect (t->ta, &trect, -1 /* -1 down == 1 up */ , 0);
- V_TRSET (&trect, height - 1, 0, height - 1, width - 1);
- VUtaFillRect (t->ta, &trect, blank_char, V_TA_NORMAL);
- MoveCursor (t, height - 1, 0);
- }
-
- /* PresentCursor()
- |
- | Change visibility of the cursor.
- | Return whether or not cursor was previously displayed.
- */
- LOCAL DV_BOOL
- PresentCursor (t, disp)
- TERMINAL *t;
- BOOLPARAM disp;
- {
- if (disp == t->curdisp)
- return disp;
- else
- {
- /* Change display of cursor in text array */
- VUtaSwapColor (t->ta, &t->curpos, 1);
- t->curdisp = disp;
- return !disp;
- }
- }
-
- /* AdjustHighlight()
- |
- | Adjust the highlighted text. If the pick is outsied the
- | highlighted region, extend the highlighted region. If it
- | is inside the region, shrink the region.
- |
- | Note that p1, p2, and p must be point to _different_ locations.
- */
-
- LOCAL DV_BOOL
- AdjustHighlight (ta, p1, p2, p)
- TEXTARRAY ta;
- TA_POSITION *p1;
- TA_POSITION *p2;
- TA_POSITION *p;
- {
- DV_BOOL rc = DV_SUCCESS; /* return code */
-
- /* Insure p1 is before p2 */
- TaPosSort (&p1, &p2);
-
- /* Adjust highlighting */
- if (TaPosCmp (p, p1) < 0) /* Expand to left */
- {
- TaPosDec (ta, p1);
- rc &= Reverse (ta, p, p1);
- p1->row = p->row;
- p1->col = p->col;
- }
- else if (TaPosCmp (p, p2) > 0) /* or expand to right */
- {
- TaPosInc (ta, p2);
- rc &= Reverse (ta, p2, p);
- p2->row = p->row;
- p2->col = p->col;
- }
-
- /* or Shrink highlighted region */
- else
- {
- TA_POSITION pmid;
-
- TaPosMidpt (ta, p1, p2, &pmid);
- if (TaPosCmp (p, &pmid) >= 0) /* shrink from right */
- {
- TaPosInc (ta, p);
- if (TaPosCmp (p, p2) <= 0)
- {
- rc &= Reverse (ta, p2, p);
- p2->row = p->row;
- p2->col = p->col;
- TaPosDec (ta, p2);
- }
- }
- else
- /* shrink from left */
- {
- TaPosDec (ta, p);
- if (TaPosCmp (p1, p) <= 0)
- {
- rc &= Reverse (ta, p1, p);
- p1->row = p->row;
- p1->col = p->col;
- TaPosInc (ta, p1);
- }
- }
- }
-
- return rc;
- }
-
- /* MoveCursor()
- |
- | Change the position of the cursor.
- */
- LOCAL void
- MoveCursor (t, row, col)
- TERMINAL *t;
- int row;
- int col;
- {
- DV_BOOL disp; /* cursor displayed? */
-
- if ((t->curpos.row != row || t->curpos.col != col) &&
- row >= 0 && col >= 0)
- {
- disp = PresentCursor (t, (DV_BOOL) NO);
- V_TPSET (&t->curpos, row, col);
- PresentCursor (t, disp);
- }
- }
-
- /* Routines to increment or decrement a TA_POSITION,
- | and to get the midpoint of two TA_POSITIONs
- */
-
- /* TaPosInc() -- Increment a TA_POSITION. */
- LOCAL void
- TaPosInc (ta, p)
- TEXTARRAY ta;
- TA_POSITION *p;
- {
- int lastcol, lastrow;
-
- lastcol = VUtaGetWidth (ta) - 1;
- lastrow = VUtaGetHeight (ta) - 1;
-
- if (p->col >= lastcol) /* last column */
- { /* move to next row */
- if (p->row < lastrow)
- {
- p->row++;
- p->col = 0;
- }
- else
- { /* position at last row/col */
- p->row = lastrow;
- p->col = lastcol;
- }
- }
- else /* next column */
- p->col++;
- }
-
- /* TaPosDec() -- Decrement a TA_POSITION. */
- LOCAL void
- TaPosDec (ta, p)
- TEXTARRAY ta;
- TA_POSITION *p;
- {
- if (p->col <= 0) /* first column */
- if (p->row > 0)
- { /* move to previous row */
- p->row--;
- p->col = VUtaGetWidth (ta) - 1;
- }
- else /* position at first row/col */
- p->row = p->col = 0;
- else /* previous column */
- p->col--;
- }
-
- /* TaPosMidpt() -- Calculate the midpoint of two TA_POSITIONs. */
- LOCAL void
- TaPosMidpt (ta, p1, p2, mid)
- TEXTARRAY ta;
- TA_POSITION *p1;
- TA_POSITION *p2;
- TA_POSITION *mid;
- {
- int lowndx, hindx, midndx, width;
-
- TaPosSort (&p1, &p2);
-
- width = VUtaGetWidth (ta);
- lowndx = p1->row * width + p1->col;
- hindx = p2->row * width + p2->col;
-
- midndx = (lowndx + hindx) / 2;
- mid->row = midndx / width;
- mid->col = midndx % width;
- }
-
- /* Reverse()
- |
- | Reverse the foreground/background colors in the specified
- | region for the specified textarray. (Turns normal video
- | into reverse video, and vice versa.)
- */
- LOCAL DV_BOOL
- Reverse (ta, p1, p2)
- TEXTARRAY ta;
- TA_POSITION *p1;
- TA_POSITION *p2;
- {
- DV_BOOL rc = DV_SUCCESS; /* return code */
- TA_POSITION tp; /* general purpose character position */
- int height, width;
- int row, start_col, end_col;
-
-
- /* Get height and width of text array */
- width = VUtaGetWidth (ta);
- height = VUtaGetHeight (ta);
-
- /* Insure p1 is before p2 */
- TaPosSort (&p1, &p2);
-
- /* Do the reversing */
- for (row = p1->row; row <= p2->row && row < height; row++)
- {
- int ncols;
-
- if (row <= p1->row)
- {
- start_col = p1->col;
- if (row >= p2->row)
- end_col = p2->col;
- else
- end_col = width - 1;
- }
- else if (row >= p2->row)
- {
- start_col = 0;
- end_col = p2->col;
- }
- else
- {
- start_col = 0;
- end_col = width - 1;
- }
- ncols = end_col - start_col + 1;
- rc &= VUtaSwapColor (ta, V_TPSET (&tp, row, start_col), ncols);
- }
- return rc;
- }
-
- /* TaPosCmp()
- |
- | Return
- | neg number if p1 < p2
- | 0 if p1 == p2
- | pos number if p1 > p2
- */
- LOCAL int
- TaPosCmp (p1, p2)
- TA_POSITION *p1;
- TA_POSITION *p2;
- {
- if (p1->row > p2->row)
- return 1;
- else if (p1->row < p2->row)
- return -1;
- else if (p1->col > p2->col)
- return 1;
- else if (p1->col < p2->col)
- return -1;
- else
- return 0;
- }
-
- /* TaPosSort()
- |
- | Place p1 and p2 in ascending order.
- */
- LOCAL void
- TaPosSort (p1, p2)
- TA_POSITION **p1;
- TA_POSITION **p2;
- {
- if (TaPosCmp (*p1, *p2) > 0)
- {
- TA_POSITION *tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- }
- }
-
- /* Repl()
- |
- | Replace all occurences of one character with another in a string.
- */
- LOCAL char *
- Repl (buf, from, to)
- char *buf;
- int from;
- int to;
- {
- char *s = buf;
-
- if (s)
- while (*s)
- {
- if (*s == from)
- *s = to;
- s++;
- }
- return buf;
- }
-
- /* Boxta()
- | Draw rectangles around the text arrays
- */
- LOCAL void
- Boxta (ta, color)
- TEXTARRAY ta;
- int color;
- {
- RECTANGLE svp;
-
- VUtaBox (ta, &svp);
- RectExpand (&svp, 1);
- GRcolor (color);
- GRrectangle (&svp.ll, &svp.ur);
- }
-
- /* PickRegion()
- |
- | Display region and get two picks from user
- | to defind rectangular region on screen.
- */
- LOCAL void
- PickRegion (msg, region)
- char *msg;
- RECTANGLE *region;
- {
- #define WHITE 15 /* white (on color display) */
- #define BLACK 0 /* black (on color display) */
-
- LOCAL DV_POINT ll =
- {1, 1}; /* close to ll corner of screen */
- OBJECT loc;
-
-
- /* display message in lower-lefthand corner of screen */
- GRcolor (WHITE);
- GRbackcolor (BLACK);
- GRch_size (DEF_TEXT_SIZE + 2, DEF_TEXT_SIZE + 2);
- GRmove (&ll);
- GRtext (msg);
-
- /* Get first point from user */
- do
- {
- loc = TloPoll (WAIT_PICK);
- }
- while (0 == VOloKey (loc));
- cpybuf ((char *) & region->ll,
- (char *) VOloScpGet (loc), sizeof (region->ll));
- Cross (®ion->ll, WHITE);
-
- /* Get second point from user */
- do
- {
- loc = TloPoll (WAIT_PICK);
- cpybuf ((char *) & region->ur,
- (char *) VOloScpGet (loc), sizeof (region->ur));
- }
- while (0 == VOloKey (loc));
- Cross (®ion->ll, BLACK);
- cpybuf ((char *) & region->ur,
- (char *) VOloScpGet (loc), sizeof (region->ur));
-
- /* Draw box and return */
- VOuVpSort (region);
- DrawBox (region, WHITE);
- }
-
- /* Cross()
- |
- | Draw cross centered at location given,
- | in given color.
- */
- LOCAL void
- Cross (pt, color)
- DV_POINT *pt;
- int color;
- {
- #define CROSS_SIZE 4
- DV_POINT p1, p2;
-
- /* horiz */
- p1.x = pt->x - CROSS_SIZE;
- p2.x = pt->x + CROSS_SIZE;
- p1.y = p2.y = pt->y;
- GRcolor (color);
- GRmove_and_vector (&p1, &p2);
-
- /* vert */
- p1.x = p2.x = pt->x;
- p1.y = pt->y - CROSS_SIZE;
- p2.y = pt->y + CROSS_SIZE;
- GRmove_and_vector (&p1, &p2);
-
- /* flush graphics output */
- GRflush ();
- }
-
- /* GetScrBox()
- |
- | Get bounding box (in screen coordinates)
- | of the given object.
- */
- LOCAL void
- GetScrBox (obj, svp)
- OBJECT obj;
- RECTANGLE *svp;
- {
- RECTANGLE
- wvp, /* bounding box in world coordinates */
- vvp, /* bounding box in virtual coordinates */
- svp_delta; /* screen coord delta from wvp */
-
- /* Make sure parameters are valid */
- if (!obj || !VOobValid (obj) || !svp)
- return;
-
- /* Get Bounding box in world coordinates */
- VOobBox (obj, &wvp, &svp_delta);
-
- /* Do a wierd conversion to virtual coordinates.
- | This works ONLY BECAUSE we are using the full screen.
- */
- vvp.ll.x = wvp.ll.x + XMAX;
- vvp.ll.y = wvp.ll.y + YMAX;
- vvp.ur.x = wvp.ur.x + XMAX;
- vvp.ur.y = wvp.ur.y + YMAX;
-
- /* Convert to screen coordinates */
- GRvcs_to_scs (&vvp.ll, &svp->ll);
- GRvcs_to_scs (&vvp.ur, &svp->ur);
-
- /* Adjust by screen coord delta */
- VOuVpSort (svp);
- VOuVpSort (&svp_delta);
- svp->ll.x -= svp_delta.ll.x;
- svp->ll.y -= svp_delta.ll.y;
- svp->ur.x += svp_delta.ur.x;
- svp->ur.y += svp_delta.ur.y;
-
- /* Force bounding box to be within the bounds of the screen */
- while (svp->ll.x < sfull_screen.ll.x)
- {
- svp->ll.x++;
- svp->ur.x++;
- }
- while (svp->ll.y < sfull_screen.ll.y)
- {
- svp->ll.y++;
- svp->ur.y++;
- }
- while (svp->ur.x > sfull_screen.ur.x)
- svp->ur.x--;
- while (svp->ur.y > sfull_screen.ur.y)
- svp->ur.y--;
- }
-
- /* DrawBox()
- |
- | Draw box specified by rectangle in given color.
- */
- LOCAL void
- DrawBox (r, color)
- RECTANGLE *r;
- int color;
- {
- GRcolor (color);
- GRrectangle (&r->ll, &r->ur);
- GRflush ();
- }
-
- /* RectExpand()
- |
- | Expand a rectangle by the given number of pixels on each side.
- */
- LOCAL void
- RectExpand (r, p)
- RECTANGLE *r;
- DV_COORD p;
- {
- r->ll.x -= p;
- r->ll.y -= p;
- r->ur.x += p;
- r->ur.y += p;
- }
-
- /* cpybuf()
- |
- | Copy the contents of one portion of memory
- | to another, one character at a time.
- */
- LOCAL void
- cpybuf (to, from, numchars)
- char *to;
- char *from;
- int numchars;
- {
- for (; numchars > 0; numchars--)
- *to++ = *from++;
- }
-
- /* Usage()
- |
- | Print usage of program and exit.
- */
- LOCAL void
- Usage (ProgName)
- char *ProgName;
- {
- fprintf (stderr, "Usage: %s [ %s [ %s [ %s ] ] ]\n",
- ProgName,
- "display_device",
- "layout_file",
- "search_path");
- exit (EXIT_ERR);
- }
-